package cloud.xuxiaowei.utils;

import cloud.xuxiaowei.utils.exception.CloudRuntimeException;
import cloud.xuxiaowei.utils.servlet.InputStreamHttpServletRequestWrapper;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
import org.springframework.util.StreamUtils;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

/**
 * @author xuxiaowei
 * @since 0.0.1
 */
public class RequestUtils {

	/**
	 * 读取请求流，支持重复获取
	 * @param request 请求
	 * @return 返回请求流字符串
	 */
	public static String getInputStreamRepeat(HttpServletRequest request) {
		InputStreamHttpServletRequestWrapper requestWrapper = new InputStreamHttpServletRequestWrapper(request);
		return getInputStream(requestWrapper);
	}

	/**
	 * 读取请求流
	 * @param request 请求
	 * @return 返回请求流字符串
	 * @see StreamUtils#copyToByteArray(InputStream)
	 * @see StreamUtils#copyToString(InputStream, Charset)
	 */
	public static String getInputStream(HttpServletRequest request) {
		try (ServletInputStream inputStream = request.getInputStream();
				InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
				BufferedReader reader = new BufferedReader(inputStreamReader)) {
			StringBuilder stringBuilder = new StringBuilder();
			String line;
			while ((line = reader.readLine()) != null) {
				stringBuilder.append(line);
			}
			return stringBuilder.toString();
		}
		catch (IOException e) {
			throw new CloudRuntimeException("读取请求流异常", e);
		}
	}

	/**
	 * 读取请求流
	 * @param inputMessage HTTP 输入消息
	 * @return 返回请求流字符串
	 * @see StreamUtils#copyToByteArray(InputStream)
	 * @see StreamUtils#copyToString(InputStream, Charset)
	 */
	public static String getInputStream(HttpInputMessage inputMessage) {
		try (InputStream inputStream = inputMessage.getBody();
				InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
				BufferedReader reader = new BufferedReader(inputStreamReader)) {
			StringBuilder stringBuilder = new StringBuilder();
			String line;
			while ((line = reader.readLine()) != null) {
				stringBuilder.append(line);
			}
			return stringBuilder.toString();
		}
		catch (IOException e) {
			throw new CloudRuntimeException("读取 HTTP 输入消息 异常", e);
		}
	}

	/**
	 * 判断是否是 application/json
	 * @param inputMessage HTTP 输入消息
	 * @return 返回判断结果
	 */
	public static boolean isApplicationJson(HttpInputMessage inputMessage) {
		HttpHeaders headers = inputMessage.getHeaders();
		MediaType contentType = headers.getContentType();
		return contentType != null && contentType.includes(MediaType.APPLICATION_JSON);
	}

	/**
	 * 获取 Content-Type 编码
	 * @param inputMessage HTTP 输入消息
	 * @return 返回 Content-Type 编码
	 */
	public static Charset getCharset(HttpInputMessage inputMessage) {
		HttpHeaders headers = inputMessage.getHeaders();
		MediaType contentType = headers.getContentType();
		if (contentType != null) {
			return contentType.getCharset();
		}
		return null;
	}

	/**
	 * 获取 Content-Type 编码
	 * @param inputMessage HTTP 输入消息
	 * @param defaultCharset 默认编码
	 * @return 返回 Content-Type 编码
	 */
	public static Charset getCharset(HttpInputMessage inputMessage, Charset defaultCharset) {
		Charset charset = getCharset(inputMessage);
		if (charset != null) {
			return charset;
		}
		return defaultCharset;
	}

}
